// 这里 制定 gulp 打包压缩规范

/*
gulp程序说明:

    gulp.src()  是  gulp 依赖包 自带的 函数程序
                作用是 设定路径 读取 指定路径中 文件内容
                *.css   当前文件夹中 子级文件 中 扩展名 是 css的文件
                *.*     当前文件夹中 子级文件 中 扩展名 和 文件名 都任意的文件 也就是 所有文件
                **      当前文件夹中 所有文件夹中的所有文件

    gulp.pipe() 是 gulp 依赖包 自带的 函数程序
                作用是 针对 gulp.src() 读取的 文件内容 执行 指定的程序
                执行效果 类似于 jQuery的链式编程
    
    gulp.dest() 是 gulp 依赖包 自带的 函数程序
                将指定的文件内容 存储到 设定的路径文件夹中
                文件名 保持 原始文件名
                设定的文件夹路径 如果不能存在 会 自动生成


    gulp.watch() 是 gulp 依赖包 自带的 函数程序
                 设定监听程序 有两个参数  gulp.watch(参数1, 参数2)
                 参数1  指定 监听文件的路径
                 参数2  指定 监听文件内容改变 执行的 打包压缩规范的名称
                        也就是 回调函数 赋值 函数名称

    gulp.series()   是 gulp 依赖包 自带的 函数程序
                    按照顺序 一个一个的 执行 设定的程序

    gulp.parallel() 是 gulp 依赖包 自带的 函数程序
                    同时执行所有设定的程序

*/





// 1,  加载 需要的依赖包
// 使用 require() 导入 下载的 依赖包

// gulp依赖包
const gulp = require('gulp');
// css依赖包
const cssmin = require('gulp-cssmin');
const autoprefixer = require('gulp-autoprefixer');
// js依赖包 
// 下载 4个 加载 2个
// @babel/preset-env  @babel/core 
// 是 gulp-babel 的 依赖包 是 gulp-babel 自己来导入加载 
const uglify = require('gulp-uglify');
const babel = require('gulp-babel');
// html依赖包
const htmlmin = require('gulp-htmlmin');
// 服务器依赖包
const webserver = require('gulp-webserver');
// 删除依赖包
const del = require('del');


// 2,   制定 打包规范

// 2-1, css打包规范 实际项目中 根据实际项目 修改设定路径
const cssHandler = function(){
    return gulp.src('./src/css/*.css')     // 指定 文件路径 读取 对应文件件路径中 文件的内容
    .pipe( autoprefixer() )                // 针对 gulp.src() 读取的 文件内容 自动添加 css兼容前缀 
    .pipe( cssmin() )                      // 针对 gulp.src() 读取的 文件内容 执行 压缩打包 规范
    .pipe( gulp.dest('./dist/css') );      // 针对 gulp.src() 读取的 文件内容 存储到 指定的 文件夹中   
}

/*
    在 package.json 中 要 添加 配置
    是 设定 css语法 兼容 浏览器版本
    定义在 json 文件中 必须要 准守 json 语法格式
    具体兼容的版本 要 按照实际程序需要设定

    "browserslist": [
        "last 2 version",   所有浏览器 兼容 最新的 两个版本就可以了
        "FireFox > 80",     单独设定 火狐浏览器 兼容 80 以上 版本
        "IOS > 7"           单独设定 苹果浏览器 兼容 7 以上 版本
    ]



*/

// 2-2, js打包规范
const jsHandler = function(){
    return gulp.src('./src/js/*.js')
    .pipe( babel( { presets:[ '@babel/env' ] } ))
    .pipe( uglify() )
    .pipe( gulp.dest( './dist/js' ) )
}

// 2-3, html打包规范
// html的打包规范 需要根据实际项目的具体要求执行
// 对 内部式 的 js程序 打包压缩效果并不好
// 实际项目中 js程序一定要写成 外部语法形式
const htmlHandler = function(){
    return gulp.src('./src/pages/*.html')
    .pipe( htmlmin({
        removeAttributeQuotes:true,     // 删除属性中属性值的双引号,如果会触发错误就不会删除
        removeComments:true,            // 删除注释
        removeScriptTypeAttributes:true,   // 删除 script标签 type属性
        removeStyleLinkTypeAttributes:true, // 删除 style标签和link标签 type属性
        collapseBooleanAttributes:true,    // 删除 布尔属性的属性值
        collapseWhitespace:true,           // 删除 标签之间的空格
        minifyCSS:true,                    // 打包压缩内部css样式程序
        minifyJS:true,                     // 打包压缩内部js程序

        // removeOptionalTags:true,        // 删除可选标签 一般不写
        // removeEmptyElements:true,       // 删除空标签 一般不写
        // removeEmptyAttributes:true,     // 删除空属性 一般不写
    }))
    .pipe( gulp.dest( './dist/pages' ) )
}

// 2-4, 不用打包 直接 存储的文件
// 例如 音频 视频 图片 后端程序 其他的插件等 
// 都不 打包 直接 存储到 dist文件夹中

// 图片
const imgHandler = function(){
    return gulp.src( './src/message/*.*' )
    .pipe( gulp.dest( './dist/message' ) )
}

// 后端
const phpHandler = function(){
    return gulp.src( './src/server/*.php' )
    .pipe( gulp.dest( './dist/server' ) )
}

// 插件
const toolsHandler = function(){
    return gulp.src( './src/tools/**' )
    .pipe( gulp.dest( './dist/tools' ) )
}




// 删除规范
// gulp 只管写 不管 删除 
// 正式执行打包压缩之前 先 删除原始打包压缩文件
// 确保 压缩文件 和 源文件 内容一致 
const delHandler = function(){
    return del( [ './dist' ] );
}

// 监听规范
// 时时监听 一旦监听的文件内容改变 会 自定执行设定的打包压缩规范
const watchHandler = function(){
    // gulp程序 监听 src文件夹中css文件夹中 扩展名是css的子级文件
    // 当 文件 内容改变是 自动执行 参数2 也就是 cssHandler 对应的 打包规范函数程序
    // 打包压缩结果中 有 "use strict" 表示 使用 严格模式
    // 所谓的严格模式 是 必须严格按照 JavaScript语法执行
    gulp.watch( './src/css/*.css' ,  cssHandler );
    gulp.watch( './src/js/*.js' ,  jsHandler );
    gulp.watch( './src/pages/*.html' ,  htmlHandler );
    gulp.watch( './src/message/*.*' ,  imgHandler );
    gulp.watch( './src/server/*.php' ,  phpHandler );
    gulp.watch( './src/tools/**' ,  toolsHandler );
}


// 服务器
// 这个服务器不是真的服务器,不能执行 后端程序
// 我们搭建这个服务器是为了给大家展示 热启动效果
const webserverHandler = function(){
    return gulp.src( './dist' )     // 设定 服务器文件来源 使用 压缩文件
    .pipe( webserver({
        host: '127.0.0.1',      // 配置服务器地址 当前是 127.0.0.1
        port: '8088',           // 设定监听端口 只要不冲突随便写
        open: './pages/index.html', // 设定服务器 首页面文件 路径是 设定 dist文件夹开始的路径
        livereload: true,       // 开启热启动
                                // 只要监听文件内容改变 服务器会自动 刷新更新内容
                                // 执行项目时 用于 调试代码非常方便
    }))
}



// 将 所有需要执行的程序 设定为 导出的默认程序执行

// 设定 gulp 打包程序的 默认执行程序内容
// 之前 运行文件 使用 node语法 node 文件名.js
// 设定 默认程序之后 可以使用 gulp 命令 调用 项目依赖中 下载的 gulp包程序
// 按照 default中 设定的 默认程序 模式 来执行
module.exports.default = gulp.series(  // 按照顺序 执行程序 先 删除原始压缩文件 重新打包压缩  之后监听
    delHandler,
    gulp.parallel( cssHandler , jsHandler , htmlHandler , imgHandler , phpHandler , toolsHandler),        // 同时执行打包压缩规范
    webserverHandler,
    watchHandler
) 



/*
    gulp的基本套路

    1,  导入依赖包

    2,  设定 指定类型文件的 打包压缩规范

    3,  设定删除规范

    4,  设定监听规范

    5,  设定 默认gulp程序
        按照顺序执行
            1,  删除原始压缩文件
            2,  同时执行所有的打包压缩规范
            3,  开启服务器
            4,  开启监听




*/ 





